/*
dbcfg.c 用于读取dbcfg配置信息
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <json-c/json.h>
#include <json-c/json_util.h>
#include "dbcfg.h"

static struct s_dbcfg *C;   //用于保存当前要处理的结构

static char * cfgpath  []={
    "/etc/dbconn.config.d/","~/.dbcfg.d/",
    ""
};

static int Q(int rtcode,const char *fmt,...){//设置错误信息并返回
    va_list ap;
    C->rtinfo[0]=0;
    C->rtcode=rtcode;
    if(rtcode)  {
        va_start(ap, fmt);
        vsnprintf(C->rtinfo,sizeof(C->rtinfo)-1,fmt,ap);
        va_end(ap);
    };
    return rtcode;
}

static int dbcfg_read2(char * cfgname,char * name)  {
    int i,j,pzgs,xmgs;//配置个数,项目（t或者d数组）个数
    char fn[1024];
    struct json_object *j0,*j1,*jt,*jd,*jitem;
    strncpy(C->cfgname,cfgname,sizeof(C->cfgname)-1);
    for(i=0;i<dbcfg_ITEM_NUM;i++){
        C->tnum=C->dnum=0;
    };
    C->cfgname[sizeof(C->cfgname)-1]=0;
    for(i=0;cfgpath[i][0];i++)  {
        snprintf(fn,sizeof(fn),"%s%s.cfg",cfgpath[i],cfgname);
        j0=json_object_from_file(fn);
        if(j0!=NULL)break;
    };
    if(j0==NULL){
        return Q(__LINE__,"打开文件%s出错",fn);
    };
    pzgs=json_object_array_length(j0);//获取配置个数
    for(i=0;i<pzgs;i++)   {
        j1=json_object_array_get_idx(j0,i);
        if(name!=NULL){//不为空需要读取name的值进行比较
            json_object_object_get_ex(j1,"name",&jitem);
            if(jitem==NULL)continue;
            if(strcmp(name,json_object_get_string(jitem))!=0)continue;
        };
//        puts(json_object_to_json_string(j1));
        json_object_object_get_ex(j1,"t",&jt);
        if(jt!=NULL){
            for(j=0,xmgs=json_object_array_length(jt);j<xmgs;j++){
                jitem=json_object_array_get_idx(jt,j);
                if(json_object_is_type(jitem, json_type_string))    {
                    strncpy(C->t[C->tnum],json_object_get_string(jitem),dbcfg_ITEM_SIZE-1);
                    C->t[C->tnum][dbcfg_ITEM_SIZE]=0;
                    C->tnum++;
                };
            };
        };
        json_object_object_get_ex(j1,"d",&jd);
        if(jd!=NULL){
            json_object_object_foreach(jd, key, val){
                memset(C->dt[C->dnum],0,dbcfg_ITEM_SIZE);
                memset(C->ds[C->dnum],0,dbcfg_ITEM_SIZE);
                C->di[C->dnum]=0;
                strncpy(C->dt[C->dnum],key,dbcfg_ITEM_SIZE-1);
                if(json_object_is_type(val,json_type_string))   {
                    strncpy(C->ds[C->dnum],json_object_get_string(val),dbcfg_ITEM_SIZE-1);
                    C->dnum++;
                };
                if(json_object_is_type(val,json_type_int))   {
                    C->di[C->dnum]=json_object_get_int(val);
                    C->dnum++;
                };
            };
        };
    };
    json_object_put(j0);//释放
    if(i==pzgs){
        return 1;//返回1表示没找到数据
    };
    return 0;
}

static int dbcfg_read(char * cfgname) {
    return dbcfg_read2(cfgname,NULL);
}

static int dbcfg_get(char * itemname)   {//根据名称在d数组里查找，返回数组下标，找不到返回-1
    int i;
    for(i=0;i<C->dnum;i++)  {
        if(strcasecmp(itemname,C->dt[i])==0)return i;
    };
    return -1;
}

static int dbcfg_geti(char * itemname,int deft) {//获取d数组标题为itemname的项对应的int值
    int i;
    i=dbcfg_get(itemname);
    if(i<0)return deft;
    return C->di[dbcfg_get(itemname)];
}

static char * dbcfg_gets(char * itemname,char * deft)  {//获取d数组标题为itemname的项对应的串指针
    int i;
    i=dbcfg_get(itemname);
    if(i<0)return deft;
    return C->ds[dbcfg_get(itemname)];
}

int dbcfg_init(struct s_dbcfg *dbc)    {
    dbc->read=dbcfg_read;
    dbc->read2=dbcfg_read2;
    dbc->geti=dbcfg_geti;
    dbc->gets=dbcfg_gets;
    C=dbc;
    return 0;
}
